local M = {}

local math_random = math.random
local math_floor  = math.floor
local table_insert = table.insert

local UPDATE_DATA_TIME = 60 * 60
local LINE_NUM   	   = 3
local ROW_NUM    	   = 5

local BIG_LOSE		= 1      --大亏类
local SMALL_LOSE	= 2      --小亏类
local SMALL_WIN		= 3		 --小赢类
local BIG_WIN		= 4      --大赢类
local FREE_TIMES	= 5      --免费次数类
local JACKPOT		= 6      --jackpot
local MAX_TYPE		= 7

local ORANGE		= 1      --橘子
local WATERMELON	= 2		 --西瓜
local LEMON			= 3		 --柠檬
local GRAPE			= 4	     --葡萄	
local KIWI			= 5	     --猕猴桃
local DINGDANG		= 6      --铃铛
local CHERRY		= 7      --樱桃
local JEWEL      	= 8      --钻石
local BONUS      	= 9      --bonus 免费次数
local SEVEN		 	= 10     --777   彩金(奖金)
local WILD       	= 11     --wild 百搭

							
local MAX_FRUIT_NUM = 12

local MAX_SHAPE_NUM = 10000

local free_times = {[3] = 3,[4] = 7,[5] = 12}

local function init_one_shape(total_weight_map,produce_rate)
	local tmp_weight_map = {}
	local one_shape = {}
	for i=1,LINE_NUM do
		if not one_shape[i] then
			one_shape[i] = {}
		end
		if not tmp_weight_map[i] then
			tmp_weight_map[i] = {}
		end
		for j=1,ROW_NUM do
			tmp_weight_map[i][j] = 0
			one_shape[i][j] = ORANGE
			local rand_num = math_random(1,total_weight_map[i][j])
			for k=1,MAX_FRUIT_NUM - 1 do
				tmp_weight_map[i][j] = tmp_weight_map[i][j] + produce_rate[i][j][k]
				if rand_num <= tmp_weight_map[i][j] then
					one_shape[i][j] = k
					break
				end
			end
		end
	end 

	return one_shape
end

local function get_line_key(one_shape,pos_record)
	local pos = pos_record[1]
	local key = one_shape[pos[1]][pos[2]]
	for _,pos in pairs(pos_record) do
		if one_shape[pos[1]][pos[2]] ~= WILD then
			key = one_shape[pos[1]][pos[2]]
			break
		end
	end

	return key
end

local function get_total_times(line_num,lines)
	local times = 0       --图案总倍数
	local free_times = 0  --总的免费次数
	local total_caijin_rate = 0--彩金比例
	for k, v in pairs(lines) do
		if v.line_num <= line_num then
			if v.fruit <= JEWEL or v.fruit == WILD then
				times = times + v.line_times 
			elseif v.fruit == BONUS then
				free_times = free_times + v.line_times
			elseif v.fruit == SEVEN then
				total_caijin_rate = total_caijin_rate + v.line_times
			end
		end	
	end
	if total_caijin_rate > 20 then
		total_caijin_rate = 20
	end

	return times,free_times,total_caijin_rate
end

local function check_line(one_shape,line_rate,award_lines,caijin_rate)
	--连线 {line_num(哪一条线),kind(水果种类),len}
	local lines = {}
	for line_num,pos_record in pairs(award_lines) do
		local key = get_line_key(one_shape,pos_record)
		local len = 0
		local line_times = 0
		for _,pos in pairs(pos_record) do
			local tmp_key = one_shape[pos[1]][pos[2]]
			if tmp_key ~= key then
				if key >= ORANGE and key <= JEWEL or key == WILD then
					if tmp_key ~= WILD then
						break
					end
				end
				if key == BONUS or key == SEVEN then
					break
				end
				
			end
			len = len + 1
		end
		
		local record_key = key
		if key == WILD then    --全部为百搭图案，把它换成倍数最大的水果(即钻石)
			key = JEWEL
		end
		if key == BONUS then  --免费次数
			if line_rate[key][len] then
				line_times = line_rate[key][len]
			end
		elseif key == SEVEN then   --奖金比例
			if caijin_rate[len] then
				line_times = caijin_rate[len]
			end
		else
			if line_rate[key][len] then
				line_times = line_rate[key][len]
			end
		end
		if line_times > 0 then
			table_insert(lines,{line_num = line_num,fruit = record_key,len = len,line_times = line_times})	
		end
	end

	return lines
end

local function get_one_shape_type(lines,bet_lines)
	--1. 大亏类：不获得任何奖励（0倍）。
	--2. 小亏类：获得少量奖励(0~1倍本金)。
	--3. 小赢类：1~5倍奖励。
	--4. 大赢类：5倍以上奖励。
	--5. 免费次数类：获得免费次数的奖励。
	--6. jackpot：中奖池的情况。
	local total_times,total_free_times,total_caijin_rate = get_total_times(bet_lines,lines)
	
	local type = BIG_WIN
	if total_free_times > 0 then       			--免费次数类
		type = FREE_TIMES
	elseif total_caijin_rate > 0 then      	    --jackpot
		type = JACKPOT
	elseif total_times == 0 then   					--大亏
		type = BIG_LOSE
	elseif total_times > 0 and total_times < bet_lines then--小亏
		type = SMALL_LOSE
	elseif total_times >= bet_lines and total_times <= 5*bet_lines  then--小赢
		type = SMALL_WIN
	elseif total_times > 5*bet_lines then                     --大赢
		type = BIG_WIN
	end 

	return type
end

local function is_sample_pos(line_pos,line,row,seven_num)
	for k,pos in pairs(line_pos) do
		if k <= seven_num and line == pos[1] and row == pos[2] then
			return true
		end
	end

	return 
end

local function find_equal_times(line_shape,line_rate,award_lines,bet_lines,caijin_rate)   --找到倍数小于9的图案
	local tiems_shape_list = {}
	for type,shape_list in pairs(line_shape) do
		for _, shape in pairs(shape_list) do
			local lines = check_line(shape,line_rate,award_lines,caijin_rate)
			local times,_,_ = get_total_times(bet_lines,lines)
			if times < 9 then
				table_insert(tiems_shape_list,shape)
			end
		end
	end
	return tiems_shape_list
end

local function create_jackpot_shape(type,bet_lines,line_shape,line_rate,award_lines,seven_rate,caijin_rate,total_weight_map,produce_rate)  --生成jackpot图案
	--1.选随机线条：从用户压线的线条中随机一条（比如压线九条就从九条中随机一条，压线一条则选中这一条）
	--2.按照概率随机三个7，四个7，五个7
	--3.剩余图案随机（且另外的发奖倍数总和不超过9倍（次要，优先考虑只能出现一条777）,新图案不能中免费次数）
	local rand_line = math_random(1,bet_lines)
	local line_pos = award_lines[rand_line]
	local total_rate = 0
	for k, v in pairs(seven_rate) do
		total_rate = total_rate + v
	end
	local seven_num = 1     --几个777连线
	local total = 0
	local rand_seven = math_random(1,total_rate)
	for k,v in pairs(seven_rate) do
		total = total + v
		if rand_seven <= total then
			seven_num = k
			break
		end
	end
	local shape_list = find_equal_times(line_shape,line_rate,award_lines,bet_lines,caijin_rate)
	local shape
	if #shape_list > 0 then
		shape = shape_list[math_random(1,#shape_list)]
	else
		shape = init_one_shape(total_weight_map,produce_rate)
	end

	local replace_fruit = BONUS
	if type == JACKPOT then
		replace_fruit = SEVEN
	end

	local new_shape = {}
	print("=======1111111111",#shape_list,replace_fruit,rand_line,rand_seven,bet_lines,seven_num,total_rate,tostring_r(seven_rate))
	for line, line_shape in pairs(shape) do
		new_shape[line] = {}
		for row,fruit in pairs(line_shape) do
			if is_sample_pos(line_pos,line,row,seven_num) then
				new_shape[line][row] = replace_fruit
			else
				if fruit == SEVEN or fruit == BONUS then    --随机一个别的替换掉吧
					new_shape[line][row] = math_random(ORANGE,JEWEL)
				else
					new_shape[line][row] = fruit
				end
			end
		end
	end

	return new_shape
end

local function get_total_weight(produce_rate)
	local total_weight_map = {}
	for line,v in pairs(produce_rate) do
		if not total_weight_map[line] then
			total_weight_map[line] = {}
		end
		for row, rate in pairs(v) do
			for _,value in pairs(rate) do
				total_weight_map[line][row] = (total_weight_map[line][row] or 0) + value
			end
		end
	end
	return total_weight_map
end


M.init_one_shape = init_one_shape
M.get_line_key = get_line_key
M.check_line = check_line
M.get_one_shape_type = get_one_shape_type
M.get_total_times = get_total_times
M.create_jackpot_shape = create_jackpot_shape
M.get_total_weight = get_total_weight

M.UPDATE_DATA_TIME = 60 * 60
M.LINE_NUM   = 3
M.ROW_NUM    = 5

M.SEVEN			= SEVEN        --777图案

M.BIG_LOSE		= BIG_LOSE     --大亏类
M.SMALL_LOSE	= SMALL_LOSE   --小亏类
M.SMALL_WIN		= SMALL_WIN	   --小赢类
M.BIG_WIN		= BIG_WIN      --大赢类
M.FREE_TIMES	= FREE_TIMES   --免费次数类
M.JACKPOT		= JACKPOT      --jackpot

M.MAX_TYPE      = MAX_TYPE

M.MAX_SHAPE_NUM = MAX_SHAPE_NUM
return M